#include "TestGraphFunctions.h"
#include"Graph.h"
#include"GraphAlgorithms.h"
#include<ctime>
#include<math.h>
#include"MakeGraph.h"
#include<typeinfo>
const int NUMBER_OF_TESTS = INT_MAX/100000000;
const int MAX = INT_MAX/100000000;





void TestGetNumberOfVertices(){
    for(int test = 0; test < NUMBER_OF_TESTS; test++){
        int vertices_number = rand()%MAX + 1;
        std::vector<edge> edges = MakeRandomEdges(vertices_number);
        ConnectivityList list(vertices_number, edges);
        if(list.GetNumberOfVertices() != vertices_number){
            throw std::logic_error("ConnectivityList.GetNumberOfVertices ERROR : wrong answer.");
        }
        ConnectivityMatrix matrix(vertices_number, edges);
        if(matrix.GetNumberOfVertices() != vertices_number){
            throw std::logic_error("ConnectivityMatrix.GetNumberOfVertices ERROR : wrong answer");
        }
    }
}

void TestGetIncidenceList(){
    for(int test = 0 ; test < NUMBER_OF_TESTS; test++){
        int vertices_number = rand() % MAX + 1;
        std::vector<edge> edges = MakeRandomEdges(vertices_number);
        std::vector<std::set< int > > answer(vertices_number);
        for(int current_edge = 0; current_edge < edges.size(); current_edge++){
            int from = edges[current_edge].from;
            int to = edges[current_edge].to;
            answer[from].insert(to);
        }
        ConnectivityList list(vertices_number, edges);
        for(int vertex = 0; vertex < vertices_number; vertex++){
            if(list.GetIncidentList(vertex) != answer[vertex]){
                throw std::logic_error("ConnectivityList.GetIncidenceList ERROR : wrong answer");
            }
        }
        ConnectivityMatrix matrix(vertices_number, edges);
        for(int vertex = 0 ;vertex < vertices_number; vertex++){
            if(matrix.GetIncidentList(vertex) != answer[vertex]){
                throw std::logic_error("ConnectivityMatrix.GetIncidenceList ERROR : wrong answer");
            }
        }
    }
}


void TestConstructor(){
    for(int test = 0; test < NUMBER_OF_TESTS; test++){
        int vertices_number = rand() % MAX + 1;
        std::vector<edge> edges = MakeRandomEdges(vertices_number);
        std::set<edge> answer (edges.begin(), edges.end());
        ConnectivityList list (vertices_number, edges);
        std::set<edge> answer_for_list;
        for(int vertex = 0; vertex < vertices_number; vertex++){
            std::set<int> incidence_list = list.GetIncidentList(vertex);
            for(std::set<int>::iterator current_vertex = incidence_list.begin(); current_vertex != incidence_list.end();current_vertex++){
                int from = vertex;
                int to = *current_vertex;
                edge new_edge (from, to);
                answer_for_list.insert(new_edge);
            }
        }
        if(answer != answer_for_list){
            throw std::logic_error("ConnectivityList constructor ERROR : wrong edges");
        }
        ConnectivityMatrix matrix(vertices_number, edges);
        std::set<edge> answer_for_matrix;
        for(int vertex = 0; vertex < vertices_number; vertex++){
            std::set<int> incidence_list = matrix.GetIncidentList(vertex);
            for(std::set<int>::iterator current_vertex = incidence_list.begin(); current_vertex != incidence_list.end();current_vertex++){
                int from = vertex;
                int to = *current_vertex;
                edge new_edge (from, to);
                answer_for_matrix.insert(new_edge);
            }
        }
    }
}

void TestMakeCompactGraph(){
    for(int test = 0; test < NUMBER_OF_TESTS;test++){
        int vertices_number = rand()%MAX + 100;
        std::vector<edge> edges = MakeFullGraphEdges(vertices_number);
        std::auto_ptr<Graph>  full_graph = MakeCompactGraph(vertices_number, edges);
        if(typeid(*full_graph) != typeid(ConnectivityMatrix)){
            throw std::logic_error("MakeCompactGraph ERROR : wrong representation has been chosen");
        }
        edges.clear();
        std::auto_ptr<Graph> graph = MakeCompactGraph(vertices_number, edges);
        if(typeid(*graph) != typeid(ConnectivityList)){
            throw std::logic_error("MakeCompactGraph ERROR : wrong representation has been chosen");
        }
    }
}

 void TestAllGraphFunctions(){
    TestGetNumberOfVertices();
    TestGetIncidenceList();
    TestConstructor();
    TestMakeCompactGraph();
}